/*
 * @Description: 
 * @version: 
 * @Author: 周曾辉
 * @Date: 2020-04-06 21:55:03
 * @LastEditors: 周曾辉
 * @LastEditTime: 2020-04-22 23:10:16
 */

import EventManager from "../../Manager/EventManager";
import { EventName } from "../../Const/EventName";
import Global from "../../Global";
import GlobalFunction from "../../Utils/GlobalFunction";
import Utils from "../../Utils/Utils";
import UserData from "../../UserData/UserData";


window.gGameCtl = null;

const { ccclass, property } = cc._decorator;

@ccclass
export default class PlayView extends cc.Component {

    enemyPool: cc.NodePool = null;
    bulletPool: cc.NodePool = null;

    @property(cc.Prefab)
    enemyPrefab: cc.Prefab = null;

    @property(cc.Prefab)
    bulletPrefab: cc.Prefab = null;

    @property(cc.Node)
    heroNode: cc.Node = null;

    _startGame: boolean = false;

    _time: number = 0;

    m_curCheckPointNum:number = 0;
    // LIFE-CYCLE CALLBACKS:
    onLoad() {
        gGameCtl = this;
        this.initEnemyPool();
        this.initBulletPool();
        this.initEvent();
        this.initData();

        this.resetHeroPos();
    }

    initData(){
        this.m_curCheckPointNum = UserData.getInstance().getCheckPointNum();
    }

    initEvent() {
        EventManager.getInstance().on(EventName.START_GAME, this.onStartGame.bind(this));
        EventManager.getInstance().on(EventName.GAME_OVER, this.onGameOver.bind(this));
        EventManager.getInstance().on(EventName.CONTINUE_GAME, this.onContinueGame.bind(this));
        EventManager.getInstance().on(EventName.PAUSE_GAME, this.onPauseGame.bind(this));
    }

    unRegisterEvents() {
        EventManager.getInstance().off(EventName.START_GAME);
        EventManager.getInstance().off(EventName.GAME_OVER);
        EventManager.getInstance().off(EventName.CONTINUE_GAME);
        EventManager.getInstance().off(EventName.PAUSE_GAME);
    }

    initEnemyPool() {
        this.enemyPool = new cc.NodePool();
        let initCount = 20;
        for (let i = 0; i < initCount; ++i) {
            let enemy = cc.instantiate(this.enemyPrefab); // 创建节点
            this.enemyPool.put(enemy); // 通过 put 接口放入对象池
        }
    }

    initBulletPool() {
        this.bulletPool = new cc.NodePool();
        let initCount = 30;
        for (let i = 0; i < initCount; ++i) {
            let bullet = cc.instantiate(this.bulletPrefab); // 创建节点
            this.bulletPool.put(bullet); // 通过 put 接口放入对象池
        }
    }


    initView() {
        if (this.enemyPool.size() > 0) {
            this.createEnemy();
        }
    }

    createEnemy() {
        let enemy = null;
        cc.log("enemyPool size:" + this.enemyPool.size());

        if (this.enemyPool.size() > 0) { // 通过 size 接口判断对象池中是否有空闲的对象
            enemy = this.enemyPool.get();
        } else { // 如果没有空闲对象，也就是对象池中备用对象不够时，我们就用 cc.instantiate 重新创建
            enemy = cc.instantiate(this.enemyPrefab);
        }
        enemy.parent = this.node; // 将生成的敌人加入节点树

        enemy.getComponent('Enemy').init(); //接下来就可以调用 enemy 身上的脚本进行初始化
    }

    

    onStartGame() {
        cc.log("PlayView 游戏开始！");
        this._startGame = true;

        let manager = cc.director.getCollisionManager();
        manager.enabled = true;

        cc.director.pause();

        this.resetHeroPos();

        this.initView();
    }

    onPauseGame() {
        cc.director.pause();
    }

    onContinueGame() {
        this._startGame = true;
        let manager = cc.director.getCollisionManager();
        manager.enabled = true;
        cc.director.resume();
    }

    resetHeroPos() {
        this.heroNode.x = this.node.x;
        this.heroNode.y = this.node.y - cc.winSize.height / 2 + 90;
    }

    onGameOver() {
        cc.log("PlayView 游戏结束！");
        this._startGame = false;
        let manager = cc.director.getCollisionManager();
        manager.enabled = false;
    }

    createBullet(count: number) {
        cc.log("bulletPool size:" + this.bulletPool.size());
        if (count == 1) {
            let bullet = null;
            if (this.bulletPool.size() > 0) { // 通过 size 接口判断对象池中是否有空闲的对象
                bullet = this.bulletPool.get();
            } else { // 如果没有空闲对象，也就是对象池中备用对象不够时，我们就用 cc.instantiate 重新创建
                bullet = cc.instantiate(this.bulletPrefab);
            }
            bullet.parent = this.node; // 将生成的敌人加入节点树

            var pos = this.heroNode.getPosition();
            pos.y += 116;
            bullet.setPosition(pos);
            pos.y += 100;
            var js = bullet.getComponent('Bullet');
            js.init();
            js.setSecondPos(pos);
        } else {
            var left = 1;
            var right = 1;
            var imgSize = 30;
            for (var i = 0; i < count; i++) {

                var offset = 0;
                if (i % 2) {
                    offset = left * imgSize;
                    offset -= imgSize / 2;
                    left++;
                } else {
                    offset = -right * imgSize;
                    offset += imgSize / 2;
                    right++;
                }
                let bullet = null;
                if (this.bulletPool.size() > 0) { // 通过 size 接口判断对象池中是否有空闲的对象
                    bullet = this.bulletPool.get();
                } else { // 如果没有空闲对象，也就是对象池中备用对象不够时，我们就用 cc.instantiate 重新创建
                    bullet = cc.instantiate(this.bulletPrefab);
                }
                bullet.parent = this.node; // 将生成的敌人加入节点树

                var pos = this.heroNode.getPosition();
                pos.y += 116;
                bullet.setPosition(pos);
                var js = bullet.getComponent('Bullet');
                js.init();
                js.setSecondPos(cc.v2(pos.x + offset, pos.y + 100));

            }
        }
    }

    onBulletKilled(bullet) {
    
        bullet.runAction(cc.show());
        bullet.parent = null;
        this.bulletPool.put(bullet); // 和初始化时的方法一样，将节点放进对象池，这个方法会同时调用节点的 removeFromParent
    }

    onEnemyKilled(enemyNode: cc.Node) {
        UserData.getInstance().addKillEnemyNum();
        EventManager.getInstance().emit(EventName.UPDATE_KILLNUM);
        enemyNode.runAction(cc.show());
        enemyNode.parent = null;
        this.enemyPool.put(enemyNode); // 和初始化时的方法一样，将节点放进对象池，这个方法会同时调用节点的 removeFromParent
    }

    update(dt) {

        let interval = Global.m_fps * 1.5;
        if (!this._startGame) {
            return;
        }

        this._time++;


        if (this._time % interval === 0) {
            this.createEnemy();
        }


        let interval2 = Global.m_fps * 0.5;

        if (this._time % interval2 === 0) {
            this.createBullet(1);
        }
        
    }


    onDestroy() {
        this.unRegisterEvents();
        this.enemyPool.clear();
    }
}



